#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
// using namespace std;
// #define CV_ALL
// #define CV_CURR
#define TO_100
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
static int current = -1;
static int count = -1;
int turn = 0;
#ifdef CV_ALL
void print_id(int id)
{
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []
            { return ready; });
    /*条件等待：
        先解锁,等待notify
        notify之后，加锁，判断ready
            ready==false 解锁并阻塞
            ready==true wait结束*/
    // 等待ready为真
    std::cout << "Thread " << id << std::endl; // handle
}
#endif
#ifdef CV_CURR
void print_id(int id)
{
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [&]
            { return current == id; });
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    std::cout << "Thread " << id << std::endl;
    ++current;
    cv.notify_all();
}
#endif
#ifdef TO_100
void print_id(int id)
{
    while (true)
    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [&]
                { return turn == id; });
        if (count > 100)
        {
            turn = (turn + 1) % 10;
            cv.notify_all();
            break;
            /*
            发现已经打印到 100 时
            立刻通知所有线程都醒来检查条件
            然后自己先 break 退出循环
            确保整个程序能够干净结束
            */
        }
        std::cout << "Thread " << id << ": " << count << std::endl;
        ++count;
        turn = (turn + 1) % 10;
        cv.notify_all();
    }
}
#endif
void go()
{
    std::unique_lock<std::mutex> lock(mtx);
#ifdef CV_ALL
    ready = true; // 设置ready为true
#endif
#ifdef CV_CURR
    current = 0;
#endif
#ifdef TO_100
    current = 1;
#endif
    cv.notify_all(); // 唤醒所有正在等待的线程
}
int main()
{
    std::thread threads[10];
    for (int i = 0; i < 10; i++)
        threads[i] = std::thread(print_id, i);
    std::cout << "10 thread ready to race..." << std::endl;
    go(); // 发令枪模式，唤醒所有等待的线程
    for (auto &th : threads)
        th.join();
    return 0;
}